using System;

namespace Sceond
{
    public class Project
    {
        public static void test()
        {
            Console.WriteLine(1.1.GetType()); // System.Double
            Console.WriteLine(1.GetType()); // System.Int32

            var a = 1.1;
            // 类型转换
            var b = (int) a;
            Console.WriteLine(b); // 1

            var c = int.MinValue;
            var d = c - 1; // 整数溢出，不会抛出异常，超出部分的进位被丢弃
            Console.WriteLine(d == int.MaxValue); // true

            try
            {
                var e = 1000000;
                var f = 1000000;
                // checked 会检查到溢出时抛出异常
                // Unhandled exception. System.OverflowException: Arithmetic operation resulted in an overflow.
                // checked 对  double 和 float 类型无作用
                int g = checked(e * f);
                Console.WriteLine(g);
                // checked 可以对整个代码块进行检测
                checked
                {
                    // do something
                    unchecked
                    {
                        // 在这里不检测溢出
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine("end");
        }

        public static void test2()
        {
            Console.WriteLine(-1.0 / 0.0); // -Infinity
            Console.WriteLine(1.0 / 0.0); // Infinity
            Console.WriteLine(0.0 / 0.0); // NaN
            Console.WriteLine(Double.NaN == Double.NaN); // false
        }

        public static void test3()
        {
            Console.WriteLine('\'');
            Console.WriteLine('\"');
            Console.WriteLine('\\');
            // \0 空(null)
            Console.WriteLine('\a'); // 警告
            Console.WriteLine('\b'); // 退格
            Console.WriteLine('\f'); // 走纸
            Console.WriteLine('\n'); // 换行
            Console.WriteLine('\r'); // 回车
            Console.WriteLine('\t'); // 水平制表符号
            Console.WriteLine('\v'); // 垂直制表符

            string a = "Hello";
            string b = "Hello";
            Console.WriteLine(a == b); // True
            Console.Write("a\n"); // 输出 a 并回车
            // @ 输出的字符串不支持转义字符，支持多行输入
            Console.Write(@"a\n"); // 输出 a\n
            Console.WriteLine("\n" + "Balala");

            int number = 56;
            // $ 和 {} 能将表达式放到字符串中计算, 并将结果转换为字符串
            Console.WriteLine($"number = {number + 2}");
        }

        public static void test4()
        {
            // 字符集合
            char[] a = new char[5];
            // 集合默认是按位取0的内存表示的值，比如 int 集合，元素默认值就是0
            Console.WriteLine(a[0]);
            a[0] = '1';
            a[1] = '2';
            a[2] = '3';
            a[3] = '4';
            a[4] = '5';
            Console.WriteLine(a[0]);
            // for 循环遍历每个元素
            for (int i = 1; i < a.Length; i++)
            {
                Console.WriteLine(a[i]);
            }

            // 初始化字符集合
            char[] b = new char[] {'0', '1', '2', '3', '4'};
            char[] c = {'0', '1', '2', '3', '4'};

            // 值类型
            ValueClass[] vArr = new ValueClass[100];
            Console.WriteLine(vArr[0].a); // 0

            // 引用类型
            ReferClass[] rArr = new ReferClass[100];
            Console.WriteLine(rArr[0]
                .a); // Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
        }

        public static void test5()
        {
            // 二维矩阵数组, 3 * 3
            int[,] matrix = new int[3, 3];
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    matrix[i, j] = i * j;
                }
            }


            // 三维矩阵数组， 3 * 3 * 3
            int[,,] matrix2 = new int[3, 3, 3]
            {
                {
                    {0, 1, 2},
                    {3, 4, 5},
                    {6, 7, 8}
                },
                {
                    {0, 1, 2},
                    {3, 4, 5},
                    {6, 7, 8}
                },
                {
                    {0, 1, 2},
                    {3, 4, 5},
                    {6, 7, 8}
                }
            };

            // 锯齿形数组
            int[][] m = new int[3][];
            for (int i = 0; i < m.Length; i++)
            {
                m[i] = new int[3];
                for (int j = 0; j < m[i].Length; j++)
                {
                    m[i][j] = i * 3 + j;
                }
            }

            int[][] m2 = new int[][]
            {
                new int[] {0, 1, 2},
                new int[] {3, 4, 5},
                new int[] {6, 7, 9}
            };

        }

        /**
         * ref 修饰符指按引用传递参数， p 和传入的参数指向同一内存位置
         */
        static void Foo(ref int p)
        {
            p = p + 1; 
            Console.WriteLine(p);
        }

       public static void test6()
        {
            var x = 9; 
            Foo(ref x); // 把 x 的引用传进去进行修改，x的值也会变化
            Console.WriteLine(x);  // 10
        }

       static void Split(string name, out string firstName, out string lastName)
       {
           int i = name.LastIndexOf(' ');
           firstName = name.Substring(0, i);
           lastName = name.Substring(i + 1);
       }
       public static void Test7()
       {
           string a, b;
           Split("Victor afra55", out a, out b);
           Console.WriteLine(a); //Victor
           Console.WriteLine(b); // afra55
           // 可以使用 _ 丢弃参数
           Split("Bfra afra55", out a, out _);
           Console.WriteLine(a); // Bfra
       }

       static void Sum(out int sum, params int[] ints)
       {
           sum = 0;
           for (int i = 0; i < ints.Length; i++)
           {
               sum += ints[i];
           }
       }
       
       public static void Test8()
       {
           Sum(out int sum, 1, 2, 3, 4, 5, 65); // 80
           Console.WriteLine(sum);
           Sum(out int sum2, new int[]{2, 3, 4, 5, 6, 1109});
           Console.WriteLine(sum2); // 1129
       }

       static void Foo(int x = 321, int y = 333)
       {
           Console.WriteLine(x + y);
       }

       public static void Test9()
       {
           Foo(y:23, x:2); // 25
           Foo(y:23);  // 344
       }
       public static void Test10()
       {
           string s1 = null;
           // 左侧表达式是 null 的时候，右侧表达式才会进行
           string s2 = s1 ?? "afra55";
           Console.WriteLine(s2); // afra55
           string s3 = s2 ?? "bfra55";
           Console.WriteLine(s3); // afra55
           
           string s4 = null;
           // 当运算符?的左侧为null的时候，该表达式的运算结果也是null而不会抛出NullReferenceException异常
           Console.WriteLine(s4?.ToString());
           Console.WriteLine(s4.ToString()); //  抛出异常 System.NullReferenceException
       }

       static void CheckType(object obj)
       {
           switch (obj)
           {
               case int i :
                   Console.WriteLine($"int {i}");
                   break;
               case float i :
                   Console.WriteLine($"float {i}");
                   break;
               case double i :
                   Console.WriteLine($"double {i}");
                   break;
               case string i :
                   Console.WriteLine($"string {i}");
                   break;
               default:
                   Console.WriteLine($"unknow {obj}");
                   break;
           }
       }

       public static void Test11()
       {
           CheckType(1); // int 1
           CheckType(1F); // float 1
           CheckType(11.1); // double 11.1
           CheckType("Hi Afra"); // string Hi Afra
           CheckType(false); // unknow False

           var x = 1;
           switch (x)
           {
               case { } i when i == 1:
                   // when 会对 case 进行预测，如果满足条件才会进来
                   Console.WriteLine("数字1");
                   break;
           }

           // 遍历 Afra55 的每一个元素，最终输出 A f r a 5 5 
           foreach (var VARIABLE in "Afra55")
           {
               Console.Write(VARIABLE + " ");
           }
       }
       
       
    }

    public struct ValueClass
    {
        public int a, b;
    }

    public class ReferClass
    {
        public int a, b;
    }

}